;*******************************************************
;* USQ support code				      *
;* 10/12/83 by Dave Rand				      *
;*******************************************************
;
; Changes made by S. Kluger to allow use under SYSLIB.
; The following SYSLIB routines are used:
;
	extrn	bdos		;BDOS call routine
	extrn	print		;In place of ILPRT
	extrn	cout		;Character out routine
;
; The following labels must be defined in the calling program:
;
	extrn	fcb		;file control block addr
	extrn	buff		;ram buffer start
	extrn	topram		;end of buffer (hi byte only)
	extrn	erext		;error exit routine
	extrn	table		;pointer to 1032 bytes
	extrn	bufull		;called when buffer full
				;(this routine processes the filled
				; buffer and then returns for more.)
;
	public	usq		;unsqueeze entry point
;
eof	equ	1ah
dle	equ	090h
;
;this is start of baseline USQ code
;
usq:	xra	a		;force init char read
	sta	numlft
	sta	rcnt		;and zero repeats
	lhld	lastmem
	shld	sob
	shld	eob
	call	getw
usq1:	call	getw		;get cksum, and store
	shld	filecrc
usq2:	call	get1
	jnz	erext
	ora	a
	jnz	usq2
usq3a:	call	getw
	shld	numvals
	lxi	d,258
	call	cmpdehl
	jc	usq3b
	call	errext
	db	13,10,'File has illegal decode size. Aborting.',0
;
usq3b:	lxi	d,table
usq4:	shld	max
	mov	a,h
	ora	l
	jz	usq5
	push	d
	call	getw
	pop	d
	xchg
	mov	m,e
	inx	h
	mov	m,d
	inx	h
	push	h
	call	getw
	xchg
	pop	h
	mov	m,e
	inx	h
	mov	m,d
	inx	h
	xchg
	lhld	max
	dcx	h
	jmp	usq4
;
usq5:	lxi	h,0
usq6:	push	h
	call	getnxt
	pop	h
	jnz	usq8
	mov	e,a
	mvi	d,0
	dad	d
	push	h
	push	psw
	LHLD	nextadr		; PT TO LOAD ADDRESS
	LDA	topram		; CHECK AGAINST END PAGE OF TPA
	CMP	H		; IF AT SAME PAGE, YES
	jnz	nofull		;buffer is not full yet
	call	bufull		;buffer full, process buffer
	lxi	h,buff		;reset buffer pointer
nofull:	pop	psw
	mov	m,a
	inx	h
	shld	nextadr
	pop	h
	jmp	usq6
;
usq8:	xchg
	lhld	filecrc
	call	cmpdehl
usq9:	rz
	call	print
	db	13,10,'ERROR - Checksum error in file ',0
	jmp	erext
;
errext:	pop	h
	mov	a,m
	ora	a
	jz	erext
	inx	h
	push	h
	call	cout
	jmp	errext
;
cmpdehl:
	mov	a,h
	cmp	d
	rnz
	mov	a,l
	cmp	e
	ret
;
get1:	lhld	eob
	xchg
	lhld	sob
	call	cmpdehl
	jz	get1r
	mov	a,m
	inx	h
	shld	sob
	cmp	a
	ret
;
get1r:	lhld	lastmem
	shld	sob
	shld	eob
get1r1:	push	h
	xchg
	mvi	c,26
	call	bdos
	lxi	d,fcb
	mvi	c,20
	call	bdos
	pop	h
	ora	a
	jnz	get1r2
	lxi	d,128
	dad	d
	xchg
	lhld	endmem
	call	cmpdehl
	xchg
	jnc	get1r1
get1r2:	shld	eob
	xchg
	lhld	sob
	call	cmpdehl
	jnz	get1
	mvi	a,255
	ora	a
	ret
;
getw:	call	get1
	jnz	badr
	push	psw
	call	get1
	jnz	badr
	mov	h,a
	pop	psw
	mov	l,a
	ret
;
badr:	call	print
	db	13,10,'Premature EOF on file... aborted.',0
	jmp	0
;
getnxt:	lda	rcnt		;see if in the middle of
	ora	a		;repeat sequence...
	jz	getn7
	dcr	a
	sta	rcnt
	lda	last
	cmp	a
	ret
getn7:	call	getn4
	cpi	dle
	jnz	getn5
	call	getn4
	ora	a
	jnz	getn6
	mvi	a,dle		;dle is encoded as dle,0
	cmp	a
	ret
getn6:	dcr	a
	dcr	a
	sta	rcnt
	lda	last
	cmp	a
	ret
getn5:	sta	last
	cmp	a
	ret
;
getn4:	lxi	d,0		;pointer @ sot
	lda	char
	mov	c,a
getn1:	lda	numlft
	ora	a
	jnz	getn2
	push	d
	call	get1
	jnz	badr
	pop	d
	mov	c,a
	mvi	a,8
getn2:	dcr	a
	sta	numlft
	mov	a,c
	rrc
	mov	c,a
	lxi	h,table
	jnc	getn3
	inx	h
	inx	h		;add 2 to point to right node
getn3:	dad	d
	dad	d
	dad	d
	dad	d		;ok.. pointing close to right plc..
	mov	e,m
	inx	h
	mov	d,m
	mov	a,d
	ani	128
	jz	getn1
	mov	a,c
	sta	char
	mov	a,d
	cpi	254		;is special eof?
	mvi	a,eof
	jz	geteof		;yup
	mov	a,e
	cma
	cmp	a
	ret
;
geteof:	pop	h
	ora	a
	ret
;
;end of baseline USQ code
;
lastmem:dw	80h
endmem:	dw	80h+127
sob:	dw	80h
eob:	dw	80h
;
nextadr:dw	buff
numlft:	ds	1
rcnt:	ds	1
filecrc:ds	2
last:	ds	1
char:	ds	1
numvals:ds	2
max:	ds	2
